Fix Android 16 CT enforcement, TrustManagerImpl fallback, and native TLS null pointer crash#178
Conversation
…6 support Frida 17.5.1 fails on Android 16 (API 36) devices due to ART runtime changes that removed `copied_methods_offset_` from the Class structure. This causes two distinct failures: 1. The bundled frida-java-bridge v7.0.10 crashes with: "Unable to find copied methods in java/lang/Thread; please file a bug" 2. frida-server 17.5.1 itself has transport-level incompatibilities on newer Android builds. Changes: - Bump FRIDA_VERSION from 17.5.1 to 17.7.3 with updated SRI hashes - Rebuild frida-java-bridge.js from v7.0.10 to v7.0.12 (uses JVMTI-based method enumeration instead of relying on removed ART internals) Tested on Google Pixel 8, Android 16, API 36. Fixes httptoolkit/httptoolkit#854
…er certs crash Three issues discovered after upgrading Frida to 17.7.3 on Android 16 (API 36): 1. Android 16 enforces Certificate Transparency (CT) via Conscrypt's CertificateTransparency.checkCT(). Proxy MITM certs lack SCTs, causing NOT_ENOUGH_SCTS failures. Fixed by hooking isCTVerificationRequired (return false) and checkCT (no-op) in the unpinning script. 2. TrustManagerImpl.verifyChain and checkTrustedRecursive throw "Trust anchor for certification path not found" on some Android 16 code paths. Added recognition in the fallback patcher to accept chains signed by the proxy CA certificate. 3. SSL_get0_peer_certificates() and realCallback() crash with "access violation accessing 0x0" for some connections. Added null ssl pointer guard and try-catch around all NativeFunction calls in the verification callback to gracefully handle invalid SSL states. Tested on Google Pixel 8, Android 16, API 36. Fixes httptoolkit/httptoolkit#855
pimterry
left a comment
There was a problem hiding this comment.
I've added comments here, but the main one really is that this PR should go to https://github.com/httptoolkit/frida-interception-and-unpinning/. That's where the scripts are defined & managed. The code here is just copied across, they shouldn't be directly modified here.
Given that I'll close this PR. There's definitely useful things I'd here I'd like to include though, so if you'd like to open a new PR against that repo with these changes and reply to my comments there, that would be very welcome.
| } | ||
| } else if ( | ||
| className === 'com.android.org.conscrypt.TrustManagerImpl' && | ||
| (methodName === 'verifyChain' || methodName === 'checkTrustedRecursive') |
There was a problem hiding this comment.
This file is for handling cases where we can't see the class or method names at all due to obfuscation. When we do have them like this, we should just put the hook into the normal hooks list in android-certificate-unpinning.js instead.
Do you know why the existing TrustedCertificateIndex patch isn't handling this case? It would be very useful to look at the Conscrypt code and see what's changed there, as it might be possible to just fix that to handle this instead.
| { | ||
| methodName: 'checkCT', | ||
| overload: '*', | ||
| replacement: () => NO_OP |
There was a problem hiding this comment.
This is actually already implemented in httptoolkit/frida-interception-and-unpinning#166 (although that hasn't been pulled into this repo yet).
The isCTVerificationRequired hook wasn't added there though. I'm open to that if there's a good reason, can you explain why that's needed?
|
|
||
| if (!peerCerts || peerCerts.isNull()) { | ||
| if (!alreadyHaveLock) pendingCheckThreads.delete(threadId); | ||
| return (realResult !== false) ? realResult : SSL_VERIFY_INVALID; |
There was a problem hiding this comment.
Feels like some of this could be better handled with a large try/finally around a larger block.
Are you adding these checks blindly to every possible call, or because you've found specific cases where these can fail? It would be useful to know what those cases are if so.
Summary
Fixes httptoolkit/httptoolkit#855
Follow-up to PR #177 (Frida 17.7.3 upgrade). After upgrading Frida, three new issues appeared on Android 16 (API 36) devices:
1. Certificate Transparency enforcement (
NOT_ENOUGH_SCTS)Android 16 enforces CT verification via
com.android.org.conscrypt.ct.CertificateTransparency.checkCT(). The proxy's MITM certificates lack Signed Certificate Timestamps since they are generated locally. Added targeted hooks inandroid-certificate-unpinning.js:isCTVerificationRequired-> returnsfalsecheckCT-> no-op (all overloads)This is consistent with how other pinning mechanisms are already disabled -- all traffic is routed through the local proxy, making CT checks unnecessary.
Reference: Android CT Policy, Conscrypt source
2. TrustManagerImpl trust anchor failures
TrustManagerImpl.verifyChainandcheckTrustedRecursivethrowTrust anchor for certification path not foundon some Android 16 code paths, despite the certificate being injected intoTrustedCertificateIndex. Added pattern recognition inandroid-certificate-unpinning-fallback.jsto catch these specific Conscrypt methods and patch them to accept chains signed by the proxy CA.Reference: frida-interception-and-unpinning#88
3. Native TLS hook null pointer crash (
access violation accessing 0x0)SSL_get0_peer_certificates()returns null for some connections, and the app's own verification callback (realCallback) also crashes when SSL internal state is invalid. Added:sslpointer guard at callback entrytry-catcharound allNativeFunctioncalls (realCallback,SSL_get0_peer_certificates,crypto_buffer_len,crypto_buffer_data)SSL_VERIFY_INVALIDon any native exceptionChanges
overrides/frida/android/android-certificate-unpinning.js: AddCertificateTransparencyCT bypass hooksoverrides/frida/android/android-certificate-unpinning-fallback.js: AddTrustManagerImpl.verifyChainandcheckTrustedRecursivefallback recognitionoverrides/frida/native-tls-hook.js: Add null pointer guards and try-catch around all native calls in verification callbackTest Plan
NOT_ENOUGH_SCTSCertificate Transparency errorsTrust anchor for certification path not founderrorsaccess violation accessing 0x0crash handled gracefully